import ajax from './ajax.js';
import {formatUnixTime} from './utils.js';
import projectInfo from '../projectInfo'
import store from '../store'
import getLocation from './getLocation.js';
import CryptoJS from 'crypto-js';
import JSEncrypt from '../utils/jsencrypt.js'

let md5 = require('md5')
/* *
 * 指定长度和进制的UUID
 * @param len       长度
 * @param radix     进制
 * @returns {string}
 */
const renderCid = (len=32, radix=16) => {
	var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
	var uuid = [],i;
	radix = radix || chars.length;
	if (len) {
		for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
	} else {
		var r;
		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
		uuid[14] = '4';
		for (i = 0; i < 36; i++) {
			if (!uuid[i]) {
				r = 0 | Math.random() * 16;
				uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
			}
		}
	}
	return uuid.join('');
}
const getNetworkType = ()=>{
	return new Promise(resolve=>{
		uni.getNetworkType({
			success(res){
				resolve(res.networkType)
			},
			fail(){
				resolve('unknown')
			}
		})
	})
}
export const handleShareActInfo = (config, options = {}, tranUrl='')=>{
	let krtNo = uni.getStorageSync('krtNo'),tranUuid = md5(krtNo+tranUrl);
	let shareActInfo = uni.getStorageSync('shareActInfo') || '{}';
	shareActInfo = JSON.parse(shareActInfo);
	// 如果是点击别人分享的链接进来，则记录根uuid、上一级uuid、传播深度
	if (options.tranRootUuid && options.tranRootUuid !== tranUuid) {
		shareActInfo.tranRootUuid = options.tranRootUuid
		shareActInfo.tranPuuid = options.tranPuuid
		shareActInfo.tranLevel = options.tranLevel * 1 + 1
		shareActInfo.startTime = new Date().getTime()
		uni.setStorageSync('shareActInfo',JSON.stringify(shareActInfo))
	}
	// 如果是第一次触发分享动作，或者上一次生成缓存的时间超过了分享有效期，则生成初始的参数
	if(!shareActInfo.tranRootUuid || (new Date().getTime() - shareActInfo.startTime > config.shareLockCycle * 3600 * 1000)){
		shareActInfo.tranRootUuid = tranUuid
		shareActInfo.tranPuuid = tranUuid
		shareActInfo.tranLevel = 0
		shareActInfo.startTime = new Date().getTime()
		uni.setStorageSync('shareActInfo',JSON.stringify(shareActInfo))
	}
	return {
		krtNo,tranUuid,shareActInfo
	}
}
const actLog = async (config, options = {}, actJson = '', tranUrl = '', returnJson = '') => {
	if(store.state.$prevMode || store.state.$editMode){
		return
	}
	let actInfo = uni.getStorageSync('actInfo') || '{}';
	actInfo = JSON.parse(actInfo);
	// 如果动作时间不存在，或者动作时间超过24小时,或者隔天了，则重置动作参数
	var ifResetActInfo = false,timeGap = new Date().getTime() - actInfo.startTime,maxTime = 24 * 3600 * 1000;
	if (!actInfo.startTime || timeGap >= maxTime) {
		ifResetActInfo = true
	}else if(timeGap < maxTime && new Date().getDate() !== new Date(actInfo.startTime).getDate()){
		ifResetActInfo = true
	}
	if(ifResetActInfo){
		actInfo.rootUuid = renderCid()
		actInfo.level = 0
		actInfo.puuid = actInfo.rootUuid
		actInfo.uuid = actInfo.rootUuid
		actInfo.startTime = new Date().getTime()
		uni.setStorageSync('actInfo', JSON.stringify(actInfo))
	}else{
		actInfo.uuid = renderCid()
	}
	
	const networkType = await getNetworkType(),phoneModel = uni.getSystemInfoSync().model;
	
	const krtNo = uni.getStorageSync('krtNo');
	var actLogObj = {
		krtNo, //用户标识
		tag: projectInfo.tag,	//项目标识
		pageCode: config.pageCode,	//页面唯一标识
		itemType: config.itemType,	//动作类型
		itemCode: config.itemCode, //动作类别
		itemName: config.itemName, //动作类别
		addrLat: '', //地理纬度
		addrLng: '', //地理经度
		addrType: 'WGS84', //坐标类型WGS84|GCJ02|BD09
		
		actCode: config.actCode, //活动Code
		themeCode: config.themeCode, //主题Code
		actTime: formatUnixTime(), //动作时间
		actHow: `{"networkStatus":"${networkType}","phoneModel":"${phoneModel}"}`,
		actJson, //自定义参数（可使用提交的业务数据）
		returnJson,	//用于一个埋点需要在接口调用之后根据返回值来触发，记录接口返回值
		times: 1,	//次数（短时间同一个重复动作可以合并）
		
		rootUuid: actInfo.rootUuid, //根UUID（初始传播者的根uuid，可设置有效期，存缓存）
		uuid: actInfo.uuid, //当前动作唯一标识
		puuid: actInfo.puuid, //上一级动作的动作标识
		level: actInfo.level, //用户在一个访问周期中，动作的步数层级
		// #ifdef MP-WEIXIN
		source: 'wechat_applet', //数据来源（IOS|Android|wechat_applet|alipay_applet|code|log）
		// #endif
		// #ifdef MP-ALIPAY
		source: 'alipay_applet', //数据来源（IOS|Android|wechat_applet|alipay_applet|code|log）
		// #endif
	}
	
	// 如果需要位置信息，则获取经纬度
	if (config.withLoc) {
		var res = await getLocation()
		actLogObj.addrLng = res.longitude
		actLogObj.addrLat = res.latitude
	}
	
	if (config.itemCode === '001002'){
		let tranUuid = md5(krtNo+tranUrl);
		if(options.tranRootUuid === tranUuid || !options.tranRootUuid){
			return
		}
		actLogObj.puuid = options.tranPuuid
	}else{
		// 本次操作结束后，记录下层级和uuid
		actInfo.level++
		actInfo.puuid = actLogObj.uuid
		uni.setStorageSync('actInfo', JSON.stringify(actInfo))
	}
	
	// 如果是分享传播动作，则加上传播的参数
	if (config.itemCode === '001001') {
		let shareActObj = handleShareActInfo(config, options, tranUrl);
		var tranUuid = shareActObj.tranUuid,shareActInfo = shareActObj.shareActInfo;
		actLogObj.tranRootUuid = shareActInfo.tranRootUuid
		actLogObj.tranPuuid = shareActInfo.tranPuuid
		actLogObj.tranLevel = shareActInfo.tranLevel
		actLogObj.tranUuid = tranUuid
		actLogObj.tranUrl = tranUrl
		// 分享出链接
		actLogObj.tranSource = 'chatList'
		actLogObj.shareKrtNo = shareActObj.krtNo
		actLogObj.takeKrtNo = ''
	}
	
	if(config.itemCode === '2'){
		actLogObj.tranSource = 'chatList'
	}
	
	if(config.itemCode === '4'){
		actLogObj.stayTime = config.stayTime
	}
	
	// 私钥（16位aes对称密钥）
	let secretKey = renderCid(16)
	// 解析之后的私钥
	let parsedSecretKey = CryptoJS.enc.Utf8.parse(secretKey)
	// 解析之后的埋点数据
	let actLogData = CryptoJS.enc.Utf8.parse(JSON.stringify(actLogObj));
	// 偏移量
	let iv = CryptoJS.enc.Utf8.parse(renderCid(16))
	// 用解析之后的私钥去加密解析之后的埋点数据,并传入偏移量
	let encryptedData = CryptoJS.AES.encrypt(actLogData, parsedSecretKey, {
		iv,
		mode: CryptoJS.mode.ECB,
		padding: CryptoJS.pad.Pkcs7
	});
	encryptedData = encryptedData.ciphertext.toString().toUpperCase();
	
	// 获取RSA加密对象
	let encrypt = new JSEncrypt();
	// 设置RSA公钥
	let publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCADHVANwxV6eKLJUbJiJ/yiEerMKljBJnvc+Tt1JVh0lGFw/+o1no9h0Ld0folgsVlO45FtSGEGSrhI4R2LbHhHg6KZACL/8ACUvPS2Rqn5M/hlAp9CxP3gfxFN8Kb67WUZkntuhQDgzkndNHVxi6FyG5iScnikrgpHwOF4YdIowIDAQAB'
	encrypt.setPublicKey(publicKey);
	// 对AES密钥进行加密
	let encryptedKey = encrypt.encrypt(secretKey);
	
	// 现在开始正式发送埋点数据
	ajax({
		url: `https://${projectInfo.development}.krtservice.com/krt-data/api/dataopt/v1/actLog/saveEncrypt`,
		header: {
			'Content-Type': 'application/json;charset=utf-8'
		},
		data: {
			data: encryptedData,
			key: encryptedKey
		},
		noErrorMsg: true
	})
}
export default actLog